package v1

import (
	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"strings"
	"zhejianglab/gin-apiserver/model"
	"zhejianglab/gin-apiserver/model/request"
	"zhejianglab/gin-apiserver/pkg/setting"
	"zhejianglab/gin-apiserver/pkg/util"
)

// AddNewAlarm create new alarm
// @Produce  json
// @Tags alarm
// @Param AlarmInfo body request.AlarmInfo true "request.AlarmInfo"
// @Success 201 {object} gin.H "{"code":201,"msg":"AddNewalarm successfully"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"AddNewalarm: alarm name is invalid"}"
// @Router /api/v1/alarm/new [post]
func AddNewAlarm(c *gin.Context) {

	var alarm request.AlarmInfo
	_ = c.ShouldBindJSON(&alarm)
	err := model.AddNewAlarm(&alarm)
	if err != nil {
		c.JSON(http.StatusCreated, gin.H{"status": http.StatusInternalServerError, "message": "Send alarm failed!", "alarm source": alarm.Source})
		return
	}

	// Create a Bearer string by appending string access token
	resposeToken, err := util.GetToken()
	if err != nil {
		c.JSON(http.StatusCreated, gin.H{"status": http.StatusInternalServerError, "message": "Send alarm failed!", "failed reason": err})
	}
	token := resposeToken.Data.Token
	imageArray := strings.Split(alarm.Images, ",")
	alarmRequest := request.AlarmRequest{
		Area:           alarm.Area,
		BySecure:       alarm.BySecure,
		DangerDesc:     alarm.DangerDesc,
		DangerTypeCode: alarm.DangerTypeCode,
		DangerTypeName: alarm.DangerTypeName,
		DepartmentID:   alarm.DepartmentID,
		DepartmentName: alarm.DepartmentName,
		Images:         imageArray,
		SelectSecure:   alarm.SelectSecure,
	}

	// 给中铁告警中心发送告警信息
	result, err := util.DoRequestAlarm("POST", setting.AlarmURL, token, alarmRequest)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "Send alarm failed!", "failed reason": err})
		return
	}

	if result.Success != true {
		c.JSON(http.StatusInternalServerError, gin.H{"status": int(result.Code), "message": "Send alarm failed!", "failed reason": result.Message})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"status": http.StatusCreated, "message": "Send alarm successfully!", "data": result})
}

// GetAlarmWithType get alarm info from db
// @Produce  json
// @Tags alarm
// @Param camera_id path int64 true "camera_id 摄像头编号"
// @Param danger_type_code path string true "danger_type_code 危险类型"
// @description 根据摄像头id和告警类型查询告警信息
// @Success 200 {object} gin.H "{"code":200,"msg":"GetAlarm successfully"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"GetAlarm failed!"}"
// @Router /api/v1/alarm [get]
func GetAlarmWithType(c *gin.Context) {

	cameraID := c.Query("camera_id")
	dangerTypeCode := c.Query("danger_type_code")
	var err error
	var conCameraID, conDangerTypeCode int64
	if cameraID == "" && dangerTypeCode == "" {
		data, err := model.GetAllAlarms()
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
			return
		}
		c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "GetAlarm successfully!", "data": data})
		return
	}

	if cameraID != "" {
		conCameraID, err = strconv.ParseInt(cameraID, 10, 64)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
			return

		}
	}

	if dangerTypeCode != "" {
		conDangerTypeCode, err = strconv.ParseInt(dangerTypeCode, 10, 64)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
			return

		}
	}

	data, err := model.GetAlarmWithType(conDangerTypeCode, conCameraID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "GetAlarm successfully!", "data": data})
}

// UpdateAlarm update alarm info
// @Produce  json
// @Tags alarm
// @Param AlarmInfo body request.AlarmInfo true "request.AlarmInfo"
// @Success 201 {object} gin.H "{"code":201,"msg":"UpdateAlarm successfully"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"UpdateAlarm: alarm name is invalid"}"
// @Router /api/v1/alarm/{id} [put]
func UpdateAlarm(c *gin.Context) {
	var err error
	data := make(map[string]interface{})
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
		return
	}

	var alarm request.AlarmInfo

	err = c.ShouldBindJSON(&alarm)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "UpdateAlarm failed!" + err.Error()})
		return
	}
	if !model.ExistAlarmByID(id) {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "alarm id is not exists failed!"})
		return
	}

	if alarm.CameraID != 0 {
		data["cameraid"] = alarm.CameraID
	}
	if alarm.Source != "" {
		data["source"] = alarm.Source
	}
	if alarm.Area != "" {
		data["area"] = alarm.Area
	}
	if alarm.BySecure != 0 {
		data["bysecure"] = alarm.BySecure
	}

	if alarm.DangerDesc != "" {
		data["danger_desc"] = alarm.Area
	}
	if alarm.DangerTypeCode != 0 {
		data["danger_type_code"] = alarm.BySecure
	}

	if alarm.DangerTypeName != "" {
		data["danger_type_name"] = alarm.Area
	}
	if alarm.DepartmentID != "" {
		data["department_id"] = alarm.BySecure
	}

	if alarm.DangerTypeName != "" {
		data["images"] = alarm.Images
	}
	if alarm.SelectSecure != 0 {
		data["select_secure"] = alarm.SelectSecure
	}

	model.UpdateAlarm(id, data)
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "UpdateAlarm successfully!", "data": data})
	return

}

// DeleteAlarm delete alarm info from db
// @Produce  json
// @Tags alarm
// @Param id path int true "ID"
// @Success 200 {object} gin.H "{"code":200,"msg":"DeleteAlarm successfully"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"DeleteAlarm failed!"}"
// @Failure 500 {object} gin.H "{"code":500,"msg":"id is invalid!"}"
// @Router /api/v1/alarm/{id} [delete]
func DeleteAlarm(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": err.Error()})
		return
	}

	valid := validation.Validation{}
	valid.Min(id, 1, "id").Message("ID必须大于0")

	if !valid.HasErrors() {
		if model.ExistAlarmByID(id) {
			model.DeleteAlarm(id)
			c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "Deletealarm successfully!"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "Deletealarm failed!"})
			return
		}
	} else {
		c.JSON(http.StatusInternalServerError, gin.H{"status": http.StatusInternalServerError, "message": "id is invalid!"})
		return
	}
}
